﻿using System;
using System.Linq;
using System.Text;
using RomanNumeralKata.Core.Constants;
using RomanNumeralKata.Core.Utility;

namespace RomanNumeralKata.Core
{
    /// <summary>
    ///     Uses looping, just another way to do the recursive implementation
    ///     Might want to pass in the arabic/roman converters rather than
    ///     have both as one class
    /// </summary>
    public class RomanNumeralBruteForceConverter : IRomanNumeralConverter
    {
        private readonly IRomanNumeralValidator _validator;

        public RomanNumeralBruteForceConverter(IRomanNumeralValidator validaor)
        {
            _validator = validaor;
        }

        /// <summary>
        ///     converts arabic number to roman numeral representation using lookup tables
        ///     and integer math, want to make that enumerator smaller
        /// </summary>
        /// <param name="arabicNumber"></param>
        /// <returns></returns>
        public string ConvertArabicToRomanNumeral(int arabicNumber)
        {
            //prob move validation to base class
            if (arabicNumber > 3999 || arabicNumber < 0)
                throw new ArgumentOutOfRangeException("arabicNumber", arabicNumber + " was not in the valid range of 0-3999");

            String romanNumeral =
                AccumulateNextNumeralsAlternateImplementation(arabicNumber);

            return romanNumeral;
        }

        /// <summary>
        ///     Converts roman numeral to arabic representation
        ///     this can be done a ton of ways
        /// </summary>
        /// <param name="romanNumeral"></param>
        /// <returns></returns>
        public int ConvertRomanNumeralToArabic(string romanNumeral)
        {
            bool isValid = _validator.IsValidRomanNumeral(romanNumeral);
            if (!isValid) throw new InvalidRomanNumeralException(romanNumeral + " is not a valid roman numeral");


            return 0;
        }

        private string AccumulateNextNumeralsAlternateImplementation(int arabicNumber)
        {
            int accumulator = arabicNumber;
            var sb = new StringBuilder(); // prob make this cleaner
            foreach (var kv in NumberRepresentations.ArabicToRomanLookup.OrderByDescending(k => k.Key))
            {
                int wholeNumber = accumulator/kv.Key;
                if (wholeNumber == 0) continue;
                for (int i = 0; i < wholeNumber; i++)
                {
                    sb.Append(kv.Value);
                }

                accumulator -= wholeNumber*kv.Key;

                if (accumulator == 0) break;
            }
            return sb.ToString();
        }


        public IRomanNumeralValidator GetValidator() // not a property because it's a service
        {
            return _validator;
        }
    }
}